package com.moon.back.util;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import com.moon.back.config.MoonExecutorConfig;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.Collection;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;

/**
 * @author zhanggenyong
 */
@Component
public class AsyncUtils {

    public static Executor asyncExecutor;

    public AsyncUtils(@Qualifier(MoonExecutorConfig.EXECUTOR_NAME) @Autowired Executor executor) {
        asyncExecutor = executor;
    }

    /**
     * 使用通用Executor异步执行
     *
     * @param runnable 可运行项
     */
    public static void execute(Runnable runnable) {
        asyncExecutor.execute(runnable);
    }

    /**
     * 使用通用Executor异步执行,等到所有方法执行完后停止
     *
     * @param runnableCollection 可运行项
     */
    @SneakyThrows
    @SuppressWarnings("rawtypes")
    public static void executeAll(Runnable... runnableCollection) {
        if (ArrayUtil.isEmpty(runnableCollection)) {
            return;
        }
        CompletableFuture[] completableFutures = Arrays.stream(runnableCollection)
                .map(runnable -> CompletableFuture.runAsync(runnable, asyncExecutor))
                .toArray(CompletableFuture[]::new);
        CompletableFuture.allOf(completableFutures).get();
    }

    /**
     * 使用通用Executor异步执行,等到所有方法执行完后停止
     *
     * @param runnableCollection 可运行项
     */
    public static void executeAll(Collection<Runnable> runnableCollection) {
        if (CollUtil.isEmpty(runnableCollection)) {
            return;
        }
        runnableCollection.removeIf(ObjectUtil::isNull);
        executeAll(runnableCollection.toArray(new Runnable[0]));
    }


}